import config from '@/config'

export interface Position {
    x: number
    y: number
}

/**
 * 判断两个位置是否相等
 */
export const positionEquals = (p1: Position, p2: Position) => {
    return p1.x === p2.x && p1.y === p2.y
}

/**
 * 从位置集合中批量移除指定位置
 */
export const removeBatchFromCollection = (collection: Array<Position>, batch: Array<Position>) => {
    return collection.filter((d) => !batch.some((p) => positionEquals(p, d)))
}

/**
 * 位置分布。top表示画布上方敌方分布。bottom表示画布下方我方坦克分布。
 */
export type Scatter = 'top' | 'bottom'

export class PositionManager {
    /**
     * 缓存（最终生成的位置都会在这统一管理）
     */
    private cache: Array<Position> = []

    /**
     * 画布上方预留的位置（用于生成敌方坦克）
     */
    private top: number = config.model.height * 2

    /**
     * 画布下方预留的位置（用于生成我方资源）
     */
    private bottom: number = config.model.height * 4

    /**
     * 随机生成位置
     */
    private position(scatter?: Scatter): Position {
        const { width: canvasWidth, height: canvasHeight } = config.canvas
        const { width: modelWidth, height: modelHeight } = config.model

        const x = Math.floor(Math.random() * (canvasWidth / modelWidth)) * modelWidth

        // 这行代码的意思是：画布上边预留2个Model的位置，画布下边预留3个Model的位置
        let y = Math.floor(Math.random() * ((canvasHeight - this.bottom - this.top) / modelHeight)) * modelHeight + this.top

        if (scatter == 'top') {
            y = Math.floor(Math.random() * (this.top / modelHeight)) * modelHeight
        } else if (scatter == 'bottom') {
            y = Math.floor(Math.random() * (this.bottom / modelHeight)) * modelHeight + (canvasHeight - this.bottom)
        }

        return { x, y }
    }

    /**
     *  判断两个位置是否重叠
     */
    private isOverlap(p1: Position, p2: Position) {
        const { width, height } = config.model
        // prettier-ignore
        return Math.max(p1.x, p2.x) < Math.min(p1.x + width, p2.x + width) &&
               Math.max(p1.y, p2.y) < Math.min(p1.y + height, p2.y + height)
    }

    /**
     * 判断指定位置是否已经在cache中生成了
     */
    private isOverlapInCache(p: Position): boolean {
        let overlap = false
        for (let i = 0; i < this.cache.length; i++) {
            if (this.isOverlap(p, this.cache[i])) {
                overlap = true
                break
            }
        }
        return overlap
    }

    /**
     * 批量生成位置
     *
     * ！可能出现的BUG，画布上所有的资源都被填满，这个方法会变成死循环
     *
     * @param count 数量
     * @param scatter 分布的位置（可选）
     * @param allowOverlap 是否可重叠
     */
    public positionBatch(count: number, scatter?: Scatter, allowOverlap = false) {
        const collection: Array<Position> = []
        while (collection.length < count) {
            const p = this.position(scatter)
            if (allowOverlap) {
                collection.push(p)
            } else {
                if (!this.isOverlapInCache(p)) {
                    collection.push(p)
                    if (!allowOverlap) this.cache.push(p)
                }
            }
        }
        return collection
    }

    /**
     * 移除指定位置
     */
    public removeBatch(positions: Array<Position>) {
        this.cache = removeBatchFromCollection(this.cache, positions)
    }
}

export default new PositionManager()
